package com.liangsui.mss.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liangsui.mss.constants.Constants;
import com.liangsui.mss.domain.DictData;
import com.liangsui.mss.domain.DictType;
import com.liangsui.mss.dto.DictTypeDto;
import com.liangsui.mss.mapper.DictDataMapper;
import com.liangsui.mss.mapper.DictTypeMapper;
import com.liangsui.mss.service.DictTypeService;
import com.liangsui.mss.vo.DataGridView;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
* @author zhang
* @description 针对表【sys_dict_type(字典类型表)】的数据库操作Service实现
* @createDate 2022-12-04 18:22:31
*/
@Service
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictType>
    implements DictTypeService {

    @Autowired
    private DictTypeMapper dictTypeMapper;

    @Autowired
    private DictDataMapper dictDataMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 查询分页
     * @param dictTypeDto
     * @return
     */
    @Override
    public DataGridView listForPage(DictTypeDto dictTypeDto) {
        QueryWrapper<DictType> wrapper = new QueryWrapper<>();
        // 分页开始
        Page<DictType> page = new Page<>(dictTypeDto.getPageNum(), dictTypeDto.getPageSize());
        // 定义模糊查询参数
        wrapper.like(StringUtils.isNotBlank(dictTypeDto.getDictName()),
                DictType.COL_DICT_NAME, dictTypeDto.getDictName());
        wrapper.like(StringUtils.isNotBlank(dictTypeDto.getDictType()),
                DictType.COL_DICT_TYPE, dictTypeDto.getDictType());
        wrapper.eq(StringUtils.isNotBlank(dictTypeDto.getStatus()),
                DictType.COL_STATUS, dictTypeDto.getStatus());
        // 大于时间
        wrapper.ge(null != dictTypeDto.getBeginTime(),
                DictType.COL_CREATE_TIME, dictTypeDto.getBeginTime());
        // 小于时间
        wrapper.le(null != dictTypeDto.getEndTime(),
                DictType.COL_CREATE_TIME, dictTypeDto.getEndTime());

        // 执行查询
        this.dictTypeMapper.selectPage(page, wrapper);
        return new DataGridView(page.getTotal(), page.getRecords());
    }

    /**
     * 同步缓存
     */
    @Override
    public void dictCacheAsync() {
        QueryWrapper<DictType> dictTypeQueryWrapper = new QueryWrapper<>();
        dictTypeQueryWrapper.eq(DictType.COL_STATUS, Constants.STATUS_TRUE);
        List<DictType> dictTypes = dictTypeMapper.selectList(dictTypeQueryWrapper);
        for (DictType dictType : dictTypes) {
            // 遍历出每一个类型字典的 数据
            QueryWrapper<DictData> dictDataQueryWrapper = new QueryWrapper<>();
            dictDataQueryWrapper.eq(DictData.COL_STATUS, Constants.STATUS_TRUE);
            dictDataQueryWrapper.eq(DictData.COL_DICT_TYPE, dictType.getDictType());
            dictDataQueryWrapper.orderByAsc(DictData.COL_DICT_SORT);
            List<DictData> dictData = dictDataMapper.selectList(dictDataQueryWrapper);
            // 转换为json
            String dictData_type = JSON.toJSONString(dictData);
            ValueOperations<String, String> value = redisTemplate.opsForValue();

            value.set(Constants.DICT_REDIS_PREFIX + dictType.getDictType(), dictData_type);
        }
    }

    /**
     * 查询所有字典类型
     *
     * @return
     */
    @Override
    public DataGridView selectAll() {
        QueryWrapper<DictType> qw = new QueryWrapper<>();
        //只查可用的
        qw.eq(DictType.COL_STATUS, Constants.STATUS_TRUE);
        return new DataGridView(null, this.dictTypeMapper.selectList(qw));
    }

    /**
     * 检查字典类型是否存在
     * 要求: 要做校验....dictType是可以进行修改的，但是它是唯一的，不能有重复的
     *
     * @param dictId
     * @param dictType
     * @return
     */
    @Override
    public Boolean checkDictTypeUnique(Long dictId, String dictType) {
        try {
            dictId = (dictId == null) ? -1L : dictId;
            QueryWrapper<DictType> qw = new QueryWrapper<>();
            qw.eq(DictType.COL_DICT_TYPE, dictType);
            DictType dictType1 = this.dictTypeMapper.selectOne(qw);
            if (null != dictType1 && dictId.longValue() != dictType1.getDictId().longValue()) {
                // 不存在
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 存在
        return false;
    }

    /**
     * 插入新的字典类型
     *
     * @param dictTypeDto
     * @return
     */
    @Override
    public int insert(DictTypeDto dictTypeDto) {
        DictType dictType = new DictType();
        // 拷贝数据
        BeanUtils.copyProperties(dictTypeDto, dictType);
        // 设置创建者、创建时间
        dictType.setCreateBy(dictTypeDto.getSimpleUser().getUserName());
        dictType.setCreateTime(DateUtil.date());
        return this.dictTypeMapper.insert(dictType);
    }

    /**
     * 修改的字典类型
     *
     * @param dictTypeDto
     * @return
     */
    @Override
    public int update(DictTypeDto dictTypeDto) {
        DictType dictType = new DictType();
        // 拷贝数据
        BeanUtils.copyProperties(dictTypeDto, dictType);
        // 设置修改人
        dictType.setCreateBy(dictTypeDto.getSimpleUser().getUserName());
        return this.dictTypeMapper.updateById(dictType);
    }

    /**
     * 根据ID删除字典类型
     *
     * @param dictIds
     * @return
     */
    @Override
    public int deleteDictTypeByIds(Long[] dictIds) {
        return null != Arrays.asList(dictIds) && Arrays.asList(dictIds).size() > 0 ? this.dictTypeMapper.deleteBatchIds(Arrays.asList(dictIds)) : -1;
    }

    /**
     * 根据ID查询一个字典类型
     * 防止为空再次请求数据库 减少压力
     *
     * @param dictId
     * @return
     */
    @Override
    public DictType selectDictTypeById(Long dictId) {
        return null != dictId ? this.dictTypeMapper.selectById(dictId) : null;
    }

    /**
     * 清空字典缓存
     * 思路： 1. 通过自定义的前缀进行模糊获取到所有的缓存数据
     * 	     2. 删除
     */
    @Override
    public void dictClearCacheAsync() {
        // 直接清空关于字典的所有缓存数据
        Set<String> keys = this.redisTemplate.keys(Constants.DICT_REDIS_PREFIX + "*");
        redisTemplate.delete(keys);
    }

}




